<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>流星雨</title>
    <style>
      body {
        background-color: #000000; /* 设置背景为黑色 */
        width: 100%;
        height: 100%;
        overflow: hidden; /* 防止出现滚动条 */
      }
      .star {
        position: absolute; /* 星星绝对定位 */
        width: 0;
        height: 0;
        opacity: 0.2; /* 初始透明度 */
        border: 2px solid transparent; /* 边框设置 */
        border-bottom: 4px solid #fff; /* 星星的颜色 */
        animation: flash 2s infinite linear; /* 星星闪烁动画 */
      }
      .star::before {
        content: ""; /* 生成伪元素 */
        position: absolute;
        left: -2px;
        top: 4px;
        border: 2px solid transparent;
        border-top: 4px solid #fff; /* 星星的上部分 */
      }
      /* 星星闪烁动画关键帧 */
      @keyframes flash {
        20% {
          opacity: 0.2;
        }
        40% {
          opacity: 0.5;
        }
        60% {
          opacity: 1;
        }
        80% {
          opacity: 0.5;
        }
        100% {
          opacity: 0.2;
        }
      }
    </style>
  </head>
  <body>

    <audio id="background-music" src="./images/星茶会.mp3" loop autoplay></audio>

    <canvas id="Meteor"></canvas>

    <script type="text/javascript">

      document.getElementById('background-music').volume = 0.3; // 设置音量为30%

      var starCount = 400; // 星星的数量
      var context; // 画布上下文

      // 初始化星星的位置
      function starInit() {
        var bg = document.querySelector("body");
        for (var i = 0; i < starCount; i++) {
          var star = document.createElement("div"); // 创建星星元素
          star.classList.add("star"); // 添加星星样式
          bg.appendChild(star); // 将星星添加到背景中
        }
      }
      
      // 随机设置星星的位置和动画延迟
      function starPosition() {
        var stars = document.querySelectorAll(".star");
        for (var i = 0; i < starCount; i++) {
          stars[i].style.left = Math.random() * window.innerWidth + "px"; // 随机X位置
          stars[i].style.top = Math.random() * window.innerHeight + "px"; // 随机Y位置
          stars[i].style.animationDelay = Math.random() * 10 + "s"; // 随机动画延迟
        }
      }

      // 初始化画布
      function init() {
        var Meteor = document.getElementById("Meteor");
        Meteor.width = window.innerWidth; // 设置画布宽度
        Meteor.height = window.innerHeight; // 设置画布高度
        context = Meteor.getContext("2d"); // 获取画布的2D上下文
      }

      // 流星雨的构造函数
      function MeteorRain() {
        this.x = Math.random() * window.innerWidth; // 随机X位置
        this.y = Math.random() * window.innerHeight; // 随机Y位置
        this.length = Math.ceil(Math.random() * 80 + 50); // 流星长度
        this.angle = 35; // 流星角度
        this.cos = Math.cos((this.angle * 3.14) / 180); // 计算cos值
        this.sin = Math.sin((this.angle * 3.14) / 180); // 计算sin值
        this.width = this.length * this.cos; // 计算流星的宽度
        this.height = this.length * this.sin; // 计算流星的高度
        this.speed = Math.ceil(Math.random() + 0.5); // 流星速度
        this.shifting_x = this.speed * this.cos; // X轴移动量
        this.shifting_y = this.speed * this.sin; // Y轴移动量

        // 计算流星的位置
        this.countPos = function () {
          this.x = this.x - this.shifting_x; // 更新X位置
          this.y = this.y + this.shifting_y; // 更新Y位置
        };
        
        //绘制流星
        this.draw = function () {
          context.save(); // 保存当前状态
          context.beginPath(); // 开始新路径
          context.lineWidth = 2; // 设置线宽
          context.globalAlpha = this.alpha; // 设置透明度
          let flag = Math.random() > 0.5 ? 1 : 0;
          var line = context.createLinearGradient(this.x, this.y, this.x + this.width, this.y - this.height); // 创建渐变
          if(flag){
            line.addColorStop(0, "white"); // 渐变起始点颜色
            line.addColorStop(0.2, "#c699ea"); // 渐变中点颜色
            line.addColorStop(1.0, "black"); // 渐变结束颜色
          }else{
             line.addColorStop(0, "white"); // 渐变起始点颜色
             line.addColorStop(0.5, "#96c9f4"); // 渐变中点颜色
             line.addColorStop(1.0, "black"); // 渐变结束颜色
          }
         
          context.strokeStyle = line; // 设置绘制颜色
          context.moveTo(this.x, this.y); // 移动到流星起始点
          context.lineTo(this.x + this.width, this.y - this.height); // 画线到流星结束点
          context.closePath(); // 关闭路径
          context.stroke(); // 绘制路径
          context.restore(); // 恢复之前保存的状态
        };

        
        // 移动流星
        this.move = function () {
          var x = this.x + this.width - this.shifting_x; // 计算流星新位置
          var y = this.y - this.height + this.shifting_y;
          context.clearRect(x - 3, y - 3, this.shifting_x + 5, this.shifting_y + 5); // 清除流星的下一帧
          this.countPos(); // 更新位置
          this.alpha -= 0.002; // 逐渐减少透明度
          this.draw(); // 绘制流星
        };
      }

      // 流星雨播放函数
      function playRains() {
        for (var n = 0; n < rainCount; n++) {
          var rain = rains[n]; // 获取流星
          rain.move(); // 移动流星
          // 当流星到达画布底部时重新初始化流星
          if (rain.y > window.innerHeight) {
            context.clearRect(rain.x, rain.y - rain.height, rain.width, rain.height);
            rains[n] = new MeteorRain(); // 创建新流星
          }
        }
        setTimeout("playRains()", 2); // 定时调用播放函数
      }

      var rainCount = 30; // 流星数量
      var rains = new Array(); // 流星数组
      init(); // 初始化画布
      starInit(); // 初始化星星
      starPosition(); // 设置星星位置
      // 创建流星并加入数组
      for (var i = 0; i < rainCount; i++) {
        var rain = new MeteorRain();
        rain.draw(); // 绘制流星
        rains.push(rain); // 添加到流星数组
      }
      playRains(); // 开始播放流星雨
    </script>
  </body>
</html>
